<template>
  <div class="version_info_container">
    <el-row :gutter="20">
      <!-- 左侧文件信息区域 -->
      <el-col :span="12">
        <el-card shadow="never">
          <!-- 文件选择和上传 -->
          <div class="flex justify-between m-b-20px">
            <div class="global_btn" @click="handleFileSelect">
              {{$t('deviceManage.select_file_label')}}
            </div>
            <el-button-group v-if="fileData">
              <div class="global_btn m-b-10px" v-globalLoading="handleFileUpload">
                {{$t('deviceManage.upload_file_label')}}
              </div>
             <!--  <div class="global_btn" @click="cancelUpload">
                {{$t('deviceManage.cancel_upload_label')}}
              </div> -->
            </el-button-group>
          </div>
          <input type="file" @change="handleFileChange" ref="fileInput" style="display: none;"/>
          <!-- 文件基本信息 -->
          <template v-if="fileData">
            <div class="info-section">
              <div class="info-item">{{$t('deviceManage.file_name_label')}}: {{fileData?.name}}</div>
              <div v-if="fileSize" class="info-item">
                {{$t('deviceManage.file_total_size_label')}}: {{fileSize}}
              </div>
              <div v-if="fileMd5" class="info-item">
                {{$t('deviceManage.file_md5_label')}}: {{fileMd5}}
              </div>
            </div>
            <!-- 固件详细信息 -->
            <div v-if="fileSize" class="firmware-info">
              <el-card v-for="item in firmwareInfos" 
                :key="item.type" 
                shadow="never" 
                class="firmware-card"
              >
                <div class="info-item">{{$t('deviceManage.file_name_label')}}: {{item.filename}}</div>
                <div class="info-item">{{$t('deviceManage.file_type_label')}}: {{item.type}}</div>
                <div class="info-item">{{$t('deviceManage.file_version_label')}}: {{item.version}}</div>
              </el-card>
            </div>
          </template>
        </el-card>
      </el-col>

      <!-- 右侧进度和状态区域 -->
      <el-col :span="12">
        <el-card shadow="never" v-if="firmwareInfos.length">
          <!-- 上传进度 -->
          <div v-if="upLoadConfig.progress && upLoadConfig.progress!==100" class="progress-section">
            <div class="progress-label">{{$t('deviceManage.upload_progress_label')}}:</div>
            <el-progress :percentage="upLoadConfig.progress" :text-inside="true" :stroke-width="20" />
          </div>

          <!-- 升级操作和进度 -->
          <div class="upgrade-section">
            <div 
              v-if="fileSize"
              v-globalLoading="handleUpgradeFirmware"
              class="global_btn"
              style="width: 100%;"
            >
              {{$t('deviceManage.upgrade_firmware_label')}}
            </div>

            <div v-if="upgradeInfo.message" class="m-t-20px">
              <div class="progress-label">{{$t('deviceManage.upgrade_progress_label')}}:</div>
              <el-progress :percentage="upgradeInfo.progress" :text-inside="true" :stroke-width="20" />
              
              <div class="log-section">
                <div class="log-title">{{$t('deviceManage.log_message_label')}}:</div>
                <div class="log_container">
                  <div v-for="item in uploadMessages" :key="item" class="log-item">{{item}}</div>
                </div>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'VersionInfo',
})
</script>
<script setup  lang="ts">
import { OtaApi } from '@/api/ota'
import { ElNotification } from 'element-plus'
import { computedUnitSize } from '@/utils/computedUtils'
import { useI18n } from 'vue-i18n'
import axios from 'axios'
const { t } = useI18n()
const fileInput = ref<any>(null)
const {upgradeType} = defineProps<{
  upgradeType:string
}>()
const handleFileSelect = () => {
    fileInput.value.click()
}
const fileData = ref<any>(null)
const handleFileChange = (event: any) => {
    fileSize.value = ''
    upgradeInfo.value = {}
    const [file] = event.target.files;
    if (!file) return;
    fileData.value = file
}
const upLoadConfig = ref<any>({
  progress:0,
  loading:false,
  isCancel:false,
})
let cancelToken:any = null
const isUploadSuccess = ref<boolean>(false)
const handleFileUpload =async () => {
  const formData = new FormData()
  formData.append('filedata', fileData.value)
  formData.append('filename', fileData.value.name)
  cancelToken = axios.CancelToken.source()
  upLoadConfig.value.loading = true
  try {
    await OtaApi.uploadFile(formData, (progressEvent: any) => {
    upLoadConfig.value.progress = Math.round((progressEvent.loaded / progressEvent.total) * 100)
  },
   cancelToken.token
  )
  ElNotification.success({
    title: t('deviceManage.upload_success_label'),
    message: `${fileData.value.name} ${t('deviceManage.upload_success_label')}`,
    duration: 1000000
  })
  upLoadConfig.value.loading = false   
  isUploadSuccess.value = true
  getFileInfo()
  } catch (error:any) {
    if(upLoadConfig.value.isCancel){
      return
    }
    ElNotification.error({
      title: t('deviceManage.upload_fail_label'),
    })
  }finally{
    upLoadConfig.value.loading = false
  }
}
const cancelUpload = () => {
    cancelToken.cancel()
    upLoadConfig.value.isCancel = true
    ElNotification.info({
      title: t('deviceManage.cancel_upload_label'),
      message: t('deviceManage.cancel_upload_message_label'),
    })
    upLoadConfig.value.progress = 0
    upLoadConfig.value.loading = false
}
const firmwareInfos = ref<any>([])
const fileSize = ref<string>('')
const fileMd5 = ref<string>('')
const getFileInfo = async () => {
  const {data}= await OtaApi.reqGetFileInfo({
    filename:fileData.value.name
  })
  fileSize.value = computedUnitSize(data.size)
  firmwareInfos.value = data.files
  fileMd5.value = data.md5
}
const upgradeInfo = ref<any>({})
let  upgradeTimer:any = null
const upgradeLoading = ref<boolean>(false)
const handleUpgradeFirmware = async () => {
  upgradeLoading.value = true
  await OtaApi.reqUpgradeFirmware({
    filename:fileData.value.name,
    type:upgradeType
  })
  await new Promise((resolve)=>{
    setTimeout(()=>{
      resolve(true)
    },5000)
  })
  await getUpgradeStatus()
}
const uploadMessages = ref<string[]>([])
const getUpgradeStatus = async () => {
  if (upgradeTimer) {
    clearTimeout(upgradeTimer)
  }
  const { data } = await OtaApi.reqGetUpgradeStatus({
    filename: fileData.value.name,
    type: upgradeType
  })
  upgradeInfo.value = data
  uploadMessages.value = data.message.split('\n')
  switch (upgradeInfo.value.status) {
    case 'success':
      ElNotification.success({
        title: t('deviceManage.upgrade_success_label'),
        message: `${fileData.value.name} ${t('deviceManage.upgrade_success_label')}`,
      })
      upgradeLoading.value = false
      return
    case 'failed':
      ElNotification.error({
        title: t('deviceManage.upgrade_fail_label'),
        message: t('deviceManage.upgrade_fail_message_label')
      })
      upgradeLoading.value = false
      return
    default:
      upgradeTimer = setTimeout(() => {
        getUpgradeStatus()
      }, 2000)
  }
}
//
</script>

<style lang="scss" scoped>
@import '@/styles/log_container.scss';
@import '@/styles/card.scss';
@import '@/styles/progress.scss';
.version_info_container {
  padding: 20px;
}

.info-section {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #04316c;
  border-radius: 4px;
}

.info-item {
  line-height: 24px;
  margin-bottom: 8px;
  &:last-child {
    margin-bottom: 0;
  }
}

.firmware-card {
  margin-bottom: 10px;
  background-color: #04316c;
  &:last-child {
    margin-bottom: 0;
  }
}

.progress-section {
  margin-bottom: 20px;
}

.progress-label {
  margin-bottom: 10px;
  font-weight: 500;
}

.upgrade-section {
  .upgrade-btn {
    width: 100%;
    margin-bottom: 20px;
  }
}

.log-section {
  margin-top: 20px;
  
  .log-title {
    margin-bottom: 10px;
    font-weight: 500;
  }
  
  .log-item {
    padding: 8px;
    border-bottom: 1px solid var(--el-border-color-lighter);
    &:last-child {
      border-bottom: none;
    }
  }
}

.m-b-20px {
  margin-bottom: 20px;
}

.m-t-20px {
  margin-top: 20px;
}
</style>
